import tkinter as tk
from tkinter import ttk,scrolledtext,filedialog,Toplevel,Canvas,BooleanVar,StringVar,DoubleVar,IntVar,messagebox
from util.Logger import Logger
from typing import Dict,Optional,Any


class SettingsWindow:
    def __init__(self,config):
        self.logger=Logger(__name__)
        self.config=config
        self.logger.info("初始化主窗口")
        self.original_api_key="sk-1fd0a7d970a64de5bd31ab4dc782e4a6"
    def show(self,parent):
        try:
            self.logger.debug("创建主窗口")
            self.window=Toplevel(parent)
            self.window.title("设置")
            self.window.geometry("600x400")
            tab_control=ttk.Notebook(self.window)
            ai_tab=ttk.Frame(tab_control)
            tab_control.add(ai_tab,text="AI服务")
            ai_canvas=Canvas(ai_tab)
            ai_scrollbar=ttk.Scrollbar(ai_tab,orient="vertical",command=ai_canvas.yview)
            ai_scrollable_frame=ttk.Frame(ai_canvas)
            ai_scrollable_frame.bind(
                "<Configure>",
                lambda e:ai_canvas.config(
                    scrollregion=ai_canvas.bbox("all")

                )
            )
            ai_canvas.create_window((0,0),window=ai_scrollable_frame,anchor="nw")
            ai_canvas.configure(yscrollcommand=ai_scrollbar.set)
            ai_canvas.pack(side="left",fill="both",expand=True)
            ai_scrollbar.pack(side="right",fill="y")
            ai_frame=ttk.LabelFrame(ai_scrollable_frame,text="AI服务设置")
            ai_frame.pack(fill="x",padx=5,pady=5)
            ttk.Label(ai_frame,text="服务提供商").grid(row=0,column=0,sticky="w",padx=5,pady=2)
            self.provider_var=StringVar()
            self.provider_combobox=ttk.Combobox(
                ai_frame,
                textvariable=self.provider_var,
                values=["DeepSeek","Zhipu","Qwen"],
                state="readonly",
                width=37
            )
            self.provider_combobox.grid(row=0,column=1,padx=5,pady=2)
            self.provider_combobox.set(self.config.get_current_provider())
            self.provider_combobox.bind("<<ComboboxSelected>>",self._update_provider_settings)
            self.logger.debug("提供商选择初始化完成")
            # 创建变量用于存储模型ID
            ttk.Label(ai_frame,text="模型ID").grid(row=1,column=0,sticky="w",padx=5,pady=2)
            self.model_id_var=StringVar(value=self.config.get("model_id",""))
            #创建下拉框，允许用户选择模型ID
            self.model_id_combobox=ttk.Combobox(
                ai_frame,
                textvariable=self.model_id_var,
                state="readonly",
                width=37
            )
            self.model_id_combobox.grid(row=1,column=1,padx=5,pady=2)
            self.logger.debug("模型ID初始化完成")
            #API key设置
            ttk.Label(ai_frame, text="API key").grid(row=2, column=0, sticky="w", padx=5, pady=2)
            self.api_key_var=StringVar(
                value=self._format_api_key(self.config.get(f"api_keys.{self.provider_var.get()}","")),

            )
            self.api_key_entry=ttk.Entry(ai_frame,textvariable=self.api_key_var,width=37)
            self.api_key_entry.grid(row=2,column=1,padx=5,pady=2)
            self.api_key_entry.bind("<FocusIn>",self._show_full_api_key)
            self.api_key_entry.bind("<FocusOut>",self._hide_api_key)
            self.logger.debug("APIkey初始化完成")
            #模型参数设置
            model_frame=ttk.LabelFrame(ai_scrollable_frame,text="模型参数")
            model_frame.pack(expand=1,fill="both",pady=10,ipady=10)
            #温度设置
            ttk.Label(model_frame,text="温度(0-1):").grid(row=0,column=0,sticky="w",padx=5,pady=2)
            self.temperature_var=DoubleVar(value=self.config.get("temperature",0.7))
            self.temperature_scale=ttk.Scale(model_frame,from_=0,to=1,variable=self.temperature_var,length=200)
            self.temperature_scale.grid(row=0,column=1,padx=5,pady=2)
            self.temperature_entry=ttk.Entry(model_frame,textvariable=self.temperature_var,width=10)
            self.temperature_entry.grid(row=0,column=2,padx=5,pady=2)
            self.logger.debug("温度初始化完成")
            #最大TOKEN数
            ttk.Label(model_frame,text="最大TOKEN数：").grid(row=1,column=0,sticky="w",padx=5,pady=2)
            self.max_tokens_var=IntVar(value=self.config.get("max_tokens",1000))
            self.max_tokens_scale=ttk.Scale(model_frame,from_=100,to=4000,variable=self.max_tokens_var,length=200,command=self._int_token)
            self.max_tokens_scale.grid(row=1,column=1,padx=5,pady=2)
            self.max_tokens_entry=ttk.Entry(model_frame,textvariable=self.max_tokens_var,width=10)
            self.max_tokens_entry.grid(row=1,column=2,padx=5,pady=2)
            self.logger.debug("最大TOKEN数初始化完成")
            #TOP P设置
            ttk.Label(model_frame,text="Top P(0-1)：").grid(row=2,column=0,sticky="w",padx=5,pady=2)
            self.top_p_var=DoubleVar(value=self.config.get("top_p",0.9))
            self.top_p_scale=ttk.Scale(model_frame,from_=0,to=1,variable=self.top_p_var,length=200)
            self.top_p_scale.grid(row=2,column=1,padx=5,pady=2)
            self.top_p_entry=ttk.Entry(model_frame,textvariable=self.top_p_var,width=10)
            self.top_p_entry.grid(row=2,column=2,padx=5,pady=2)
            self.logger.debug("Top P数初始化完成")
            #流式输出设置
            self.stream_var=BooleanVar(value=self.config.get("stream",True))
            ttk.Checkbutton(model_frame,text="流式输出",variable=self.stream_var).grid(row=3,column=0,sticky="w",columnspan=3,padx=5,pady=2)
            self.logger.debug("流式输出设置成功")
            editor_tab=ttk.Frame(tab_control)
            tab_control.add(editor_tab,text="编辑器")
            editor_frame=ttk.LabelFrame(editor_tab,text="编辑器设置")
            editor_frame.pack(fill="x",padx=5,pady=5)
            #字体设置
            ttk.Label(editor_frame,text="字体：").grid(row=0,column=0,sticky="w",padx=5,pady=2)
            self.font_family_entry=ttk.Entry(editor_frame,width=20)
            self.font_family_entry.grid(row=0,column=1,padx=5,pady=2)
            self.font_family_entry.insert(0,self.config.get("font_family","黑体"))
            self.logger.debug("字体设置成功")
            #字体大小设置
            ttk.Label(editor_frame,text="字体大小：").grid(row=1,column=0,sticky="w",padx=5,pady=2)
            self.font_size_entry=ttk.Entry(editor_frame,width=20)
            self.font_size_entry.grid(row=1,column=1,padx=5,pady=2)
            self.font_size_entry.insert(0,self.config.get("font_size",18))
            self.logger.debug("字体大小设置成功")
            #日志级别设置
            ttk.Label(editor_frame, text="日志级别：").grid(row=2, column=0, sticky="w", padx=5, pady=2)
            self.log_level_var=StringVar()
            self.log_level_combobox=ttk.Combobox(editor_frame,
                                                 textvariable=self.log_level_var,
                                                 values=["DEBUG","INFO","WARNING","ERROR","CRITICAL"],
                                                 state="readonly",
                                                 width=10
                                                 )
            self.log_level_combobox.grid(row=2,column=1,padx=5,pady=2)
            self.log_level_combobox.set(self.config.get("log_level","INFO"))
            self.logger.debug("日志初始化完成")

            tab_control.pack(expand=1, fill="both", pady=10, ipady=10)
            #创建保存按钮
            save_button=ttk.Button(self.window,text="保存设置",command=self._save_settings)
            save_button.pack(side="bottom",pady=10)
            self.logger.debug("按钮设置成功")
            self.logger.info("设置窗口显示成功")
        except Exception as e:
            self.logger.critical(f"显示窗口异常{str(e)}",exc_info=True)

    def _update_provider_settings(self,event=None):
        try:
            provider=self.provider_var.get()
            self.config.set_current_provider(provider)
            model_options={
                "DeepSeek":["deepseek-chat","deepseek-reasoner"],
                "Zhipu":["glm-4-flash","glm-4v-flash"],
                "Qwen":["qwen-turbo","qwen-plus"]
            }
            self.model_id_combobox["values"]=model_options.get(provider,[])
            self.model_id_combobox.current(0)
            self.logger.debug(f"更新成功{provider}")
        except Exception as e:
            self.logger.debug(f"更新失败{str(e)}",exc_info=True)

    def _format_api_key(self,api_key:str):
        if len(api_key)<=16:
            return api_key
        return f"{api_key[:8]}****{api_key[-8:]}"

    def _show_full_api_key(self,event=None):
        try:
            current_provider=self.provider_var.get().lower()
            api_key=self.config.get(f"api_keys.{current_provider}","")
            self.original_api_key=api_key
            self.api_key_var.set(api_key)
        except Exception as e:
            self.logger.error(f"显示失败{str(e)}")

    def _hide_api_key(self,event=None):
        try:
            if self.api_key_entry.get()!=self._format_api_key(self.original_api_key):
                self.original_api_key=self.api_key_entry.get()
            self.api_key_var.set(self._format_api_key(self.original_api_key))
        except Exception as e:
            self.logger.error(f"显示隐藏失败{str(e)}")

    def _int_token(self,value):
        self.max_tokens_var.set(round(float(value)))

    def _save_settings(self):
        try:
            self.logger.info("保存设置")
            current_provider=self.provider_var.get().lower()
            self.config.set_current_provider(current_provider)
            self.config.set_api_key(current_provider,self.original_api_key)
            self.config.set("model_id",self.model_id_var.get())
            self.config.set("temperature",float(self.temperature_entry.get()))
            self.config.set("max_token",int(self.max_tokens_entry.get()))
            self.config.set("top_p",float(self.top_p_entry.get()))
            self.config.set("stream",self.stream_var.get())
            self.config.set("font_family",self.font_family_entry.get())
            self.config.set("font_size",int(self.font_size_entry.get()))
            self.config.set("log_level",self.log_level_var.get())
            self.config._save_config()
            self.logger.info("保存设置成功")
            messagebox.showinfo("成功","设置已保存")

        except ValueError as e:
            self.logger.error(f"设置错误{str(e)}", exc_info=True)
            messagebox.showerror("错误",f"设置值格式错误{str(e)}")